#include <gtest/gtest.h>
#include <gmock/gmock.h>

#define private public
#define protected public
#include <section.h>
#undef private
#undef protected

using namespace std;
using ::testing::ContainerEq;


class RectangleTest: public::testing::Test
{
    protected:
        // Declares the Rectangles
        double width = 20, height = 40;
        Rectangle sect1_ = Rectangle(1, width, height);

        // Rectangle sect2_ = Rectangle(2, 1.0, 0.0);

        // other data
        double area = width * height;
        double Sy = 0.0;
        double Sz  = 0.0;
        double CGy = Sz / area;
        double CGz = Sy / area;

        double Iyy = height * pow(width, 3.0) / 12.0;
        double Izz = width * pow(height, 3.0) / 12.0;
        double Iyz = 0.0;
        // You can remove any or all of the following functions if their bodies
        // would be empty.
        RectangleTest()
        {
            // You can do set-up work for each test here.
        };

        ~RectangleTest()
        {
            // You can do clean-up work that doesn't throw exceptions here.
        };

        // If the constructor and destructor are not enough for setting up
        // and cleaning up each test, you can define the following methods:
        void SetUp() override
        {
            // Code here will be called immediately after the constructor
            // (right before each test).
            cout << "Set Up Rectangle Test" << endl;
        };

        void TearDown() override
        {
            // Code here will be called immediately after each test (right
            // before the destructor).
        };

        // Class members declared here can be used by all tests in the test
        // suite for Foo.
};


// Tests that the Rectangle::Rectangle() method does Abc.
TEST_F(RectangleTest, IsEmptyInitiate)
{
    cout << "\n---------- RectangleTest IsEmptyInitiate ----------" << endl;
    cout << "check id... " << endl;
    EXPECT_EQ(sect1_.id(), 1);
    // EXPECT_EQ(sect2_.id(), 2);

    cout << "check type... " << endl;
    char type[] = "Rectangle";
    EXPECT_STREQ(type, sect1_.type_.c_str());

    cout << "check A... " << endl;
    EXPECT_DOUBLE_EQ(area, sect1_.A_);
    // EXPECT_DOUBLE_EQ(0.0, sect2_.A_);

    cout << "check Sy... " << endl;
    EXPECT_DOUBLE_EQ(Sy, sect1_.Sy_);

    cout << "check Sz... " << endl;
    EXPECT_DOUBLE_EQ(Sz, sect1_.Sz_);

    cout << "check CGy... " << endl;
    EXPECT_DOUBLE_EQ(CGy, sect1_.CGy_);

    cout << "check CGz... " << endl;
    EXPECT_DOUBLE_EQ(CGz, sect1_.CGz_);

    cout << "check SHy... " << endl;
    EXPECT_DOUBLE_EQ(0.0, sect1_.SHy_);

    cout << "check SHz... " << endl;
    EXPECT_DOUBLE_EQ(0.0, sect1_.SHz_);

    cout << "check Iyy_... " << endl;
    EXPECT_DOUBLE_EQ(Iyy, sect1_.Iyy_);

    cout << "check Izz_... " << endl;
    EXPECT_DOUBLE_EQ(Izz, sect1_.Izz_);

    cout << "check Iyz_... " << endl;
    EXPECT_DOUBLE_EQ(Iyz, sect1_.Iyz_);
};


// Tests that the Rectangle::calcArea() method.
TEST_F(RectangleTest, A)
{
    cout << "\n---------- RectangleTest A ----------" << endl;
    cout << "check A..." << endl;
    EXPECT_DOUBLE_EQ(area, sect1_.A());
};


// Tests that the Rectangle::Sy() method.
TEST_F(RectangleTest, Sy)
{
    cout << "\n---------- RectangleTest calcSy ----------" << endl;
    cout << "do nothing..." << endl;
    EXPECT_DOUBLE_EQ(Sy, sect1_.Sy());
};


// Tests that the Rectangle::Sz() method does Abc.
TEST_F(RectangleTest, Sz)
{
    cout << "\n---------- RectangleTest Sz ----------" << endl;
    cout << "do nothing..." << endl;
    EXPECT_DOUBLE_EQ(Sz, sect1_.Sz());
};


// Tests that the Rectangle::calcCGz() method does Abc.
TEST_F(RectangleTest, CGz)
{
    cout << "\n---------- RectangleTest CGz ----------" << endl;
    cout << "do nothing..." << endl;
    EXPECT_DOUBLE_EQ(CGz, sect1_.CGz());
};


// Tests that the Rectangle::SHy() method does Abc.
TEST_F(RectangleTest, SHy)
{
    cout << "\n---------- RectangleTest SHy ----------" << endl;
    cout << "do nothing..." << endl;
    EXPECT_DOUBLE_EQ(0.0, sect1_.SHy());
};


// Tests that the Rectangle::SHz() method does Abc.
TEST_F(RectangleTest, SHz)
{
    cout << "\n---------- RectangleTest SHz ----------" << endl;
    cout << "do nothing..." << endl;
    EXPECT_DOUBLE_EQ(0.0, sect1_.SHz());
};


// Tests that the Rectangle::Iyy() method does Abc.
TEST_F(RectangleTest, Iyy)
{
    cout << "\n---------- RectangleTest Iyy ----------" << endl;
    cout << "do nothing..." << endl;
    EXPECT_DOUBLE_EQ(Iyy, sect1_.Iyy());
};


// Tests that the Rectangle::calcIzz() method does Abc.
TEST_F(RectangleTest, Izz)
{
    cout << "\n---------- RectangleTest calcIzz ----------" << endl;
    cout << "do nothing..." << endl;
    EXPECT_DOUBLE_EQ(Izz, sect1_.Izz());
};


// Tests that the Rectangle::calcIyz() method does Abc.
TEST_F(RectangleTest, Iyz)
{
    cout << "\n---------- RectangleTest calcIyz ----------" << endl;
    cout << "do nothing..." << endl;
    EXPECT_DOUBLE_EQ(Iyz, sect1_.Iyz());
};


// Tests that the Rectangle::info() method does Abc.
TEST_F(RectangleTest, info)
{
    // do not need to test
};
